
package com.zdkj.subway.stm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.subway.stm.dto.in.SwBomSettleCycleCalculateDTO;
import com.zdkj.subway.stm.dto.in.SwBomSettleSubmitDTO;
import com.zdkj.subway.stm.dto.in.SwStMarketingTicketDTO;
import com.zdkj.subway.stm.entity.*;
import com.zdkj.subway.stm.mapper.SwStBomSettleMapper;
import com.zdkj.subway.stm.service.SwStBomSettleService;
import com.zdkj.subway.stm.service.SwStConductorSettleService;
import com.zdkj.subway.stm.service.SwStMarketingTicketService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.management.remote.rmi._RMIConnection_Stub;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;

/**
 * bom结算
 *
 * @author songtuo
 * @date 2020-08-09 17:14:32
 */
@Service
public class SwStBomSettleServiceImpl extends ServiceImpl<SwStBomSettleMapper, SwStBomSettle> implements SwStBomSettleService {

    @Autowired
    SwStConductorSettleService swStConductorSettleService;

    @Autowired
    SwStMarketingTicketService swStMarketingTicketService;

    @Override
    public boolean longCycleSellt(SwBomSettleCycleCalculateDTO cycleCalculateDTO) {
        SwStBomSettle swStBomSettleObj = ObjectUtils.getDefaultObj(SwStBomSettle.class);
        LocalDate startTime = cycleCalculateDTO.getStartTime();
        LocalDate endTime = cycleCalculateDTO.getEndTime();
        List<String> nfJobNoList = cycleCalculateDTO.getNfJobNoList();
        //首先去查售票员日结数据
        for (String nfJobNo : nfJobNoList) {
            SwStBomSettle swStBomSettle = new SwStBomSettle();
            BeanUtil.copyProperties(cycleCalculateDTO, swStBomSettle, CopyOptions.create().setIgnoreNullValue(true));
            BeanUtil.copyProperties(swStBomSettleObj, swStBomSettle, CopyOptions.create().setIgnoreNullValue(true));
            List<SwStConductorSettle> list = swStConductorSettleService.list(new QueryWrapper<SwStConductorSettle>().lambda().likeRight(SwStConductorSettle::getConductorJobNo, nfJobNo)
                    .eq(SwStConductorSettle::getStationCode, swStBomSettleObj.getStationCode()).eq(SwStConductorSettle::getLineCode, swStBomSettleObj.getLineCode())
                    .ge(SwStConductorSettle::getWorkingStartTime, startTime).le(SwStConductorSettle::getWorkingStartTime, endTime));
            BigDecimal cashAmount = new BigDecimal(0D);
            BigDecimal totaladanceAmount = new BigDecimal(0D);
            for (SwStConductorSettle settle : list) {
                BigDecimal realAmount = settle.getRealAmount();
                BigDecimal adanceAmount = settle.getAdanceAmount();
                cashAmount = cashAmount.add(realAmount).add(adanceAmount);
                totaladanceAmount = totaladanceAmount.add(adanceAmount);
                if (swStBomSettle.getConductorName() == null) {
                    swStBomSettle.setConductorName(settle.getConductorName());
                }
                if (swStBomSettle.getDeviceOperatorNum() == null) {
                    swStBomSettle.setDeviceOperatorNum(settle.getDeviceOperateNum());
                }
            }
            //实收款金额 TODO 待确认 合并方式需要确认
            swStBomSettle.setCashReceiptAmount(cashAmount);
            //预收款金额
            swStBomSettle.setAdvanceAmount(totaladanceAmount);
            //电子金额设置
            BigDecimal totalElectronicAmount = getElectronicAmount(swStBomSettleObj, startTime, endTime, nfJobNo, swStBomSettle);
            if (swStBomSettle.getConductorName() == null) {
                // 日结算数据 和 电子金额都没有录入 异常异常不处理
                continue;
            }
            swStBomSettle.setElectronicAmount(totalElectronicAmount);
            swStBomSettle.setSellStartTime(startTime);
            swStBomSettle.setSellEndTime(endTime);
            swStBomSettle.setSettlementTime(LocalDate.now());
            swStBomSettle.setConductorJobNo(nfJobNo);
            SwStBomSettle existBomSettle = getOne(new QueryWrapper<SwStBomSettle>().lambda().eq(SwStBomSettle::getLineCode, swStBomSettle.getLineCode())
                    .eq(SwStBomSettle::getStationCode, swStBomSettle.getStationCode())
                    .eq(SwStBomSettle::getSellStartTime, swStBomSettle.getSellStartTime()).eq(SwStBomSettle::getSellEndTime, swStBomSettle.getSellEndTime())
                    .eq(SwStBomSettle::getConductorJobNo, swStBomSettle.getConductorJobNo()));
            if (null != existBomSettle) {
                //重复多次覆盖 主键冲突
                removeById(existBomSettle.getId());
            }
            save(swStBomSettle);
        }
        return true;
    }

    /**
     * 状态提交
     *
     * @param swBomSettleSubmitDTO
     * @return
     */
    @Override
    public boolean submit(SwBomSettleSubmitDTO swBomSettleSubmitDTO) {
        List<Integer> ids = swBomSettleSubmitDTO.getIds();
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        for (Integer id : ids) {
            SwStBomSettle swStBomSettle = getById(id);
            List<SwStConductorSettle> list = swStConductorSettleService.list(new QueryWrapper<SwStConductorSettle>().lambda().like(SwStConductorSettle::getConductorJobNo, swStBomSettle.getConductorJobNo() + "%")
                    .eq(SwStConductorSettle::getStationCode, swStBomSettle.getStationCode()).eq(SwStConductorSettle::getLineCode, swStBomSettle.getLineCode())
                    .ge(SwStConductorSettle::getWorkingStartTime, swStBomSettle.getSellStartTime()).le(SwStConductorSettle::getWorkingStartTime, swStBomSettle.getSellEndTime()));
            if (CollectionUtils.isNotEmpty(list)) {
                list.forEach(x -> x.setApprovalStatus(swBomSettleSubmitDTO.getStatus()));
                swStConductorSettleService.updateBatchById(list);
            }
            List<SwStMarketingTicket> marketingTickets = swStMarketingTicketService.list(new QueryWrapper<SwStMarketingTicket>().lambda().eq(SwStMarketingTicket::getStationCode, swStBomSettle.getStationCode())
                    .eq(SwStMarketingTicket::getLineCode, swStBomSettle.getLineCode()).ge(SwStMarketingTicket::getOpertorTime, swStBomSettle.getSellStartTime())
                    .le(SwStMarketingTicket::getOpertorTime, swStBomSettle.getSellEndTime()).eq(SwStMarketingTicket::getConductorJobNo, swStBomSettle.getConductorJobNo()));
            if (CollectionUtils.isNotEmpty(marketingTickets)) {
                marketingTickets.forEach(x -> x.setApprovalStatus(swBomSettleSubmitDTO.getStatus()));
                swStMarketingTicketService.updateBatchById(marketingTickets);
            }
            BeanUtil.copyProperties(swBomSettleSubmitDTO, swStBomSettle, CopyOptions.create().setIgnoreNullValue(true));
            swStBomSettle.setApprovalStatus(swBomSettleSubmitDTO.getStatus());
            updateById(swStBomSettle);
        }
        return true;
    }

    private BigDecimal getElectronicAmount(SwStBomSettle swStBomSettleObj, LocalDate startTime, LocalDate endTime, String nfJobNo, SwStBomSettle swStBomSettle) {
        List<SwStMarketingTicket> marketingTickets = swStMarketingTicketService.list(new QueryWrapper<SwStMarketingTicket>().lambda().eq(SwStMarketingTicket::getStationCode, swStBomSettleObj.getStationCode())
                .eq(SwStMarketingTicket::getLineCode, swStBomSettleObj.getLineCode()).ge(SwStMarketingTicket::getOpertorTime, startTime)
                .le(SwStMarketingTicket::getOpertorTime, endTime).eq(SwStMarketingTicket::getConductorJobNo, nfJobNo));
        BigDecimal totalElectronicAmount = new BigDecimal(0D);
        for (SwStMarketingTicket marketingTicket : marketingTickets) {
            if (swStBomSettle.getConductorName() == null) {
                swStBomSettle.setConductorName(marketingTicket.getConductorName());
            }
            Integer id = marketingTicket.getId();
            SwStMarketingTicketDTO swStMarketingTicketDTO = swStMarketingTicketService.queryDetailsById(id);
            List<SwStMarketingTicketGroupSell> ticketGroupSells = swStMarketingTicketDTO.getTicketGroupSells();
            for (SwStMarketingTicketGroupSell ticketGroupSell : ticketGroupSells) {
                if (ticketGroupSell.getPayMethod().equals("1") || ticketGroupSell.getPayMethod().equals("2") || ticketGroupSell.getPayMethod().equals("3")) {
                    totalElectronicAmount = totalElectronicAmount.add(ticketGroupSell.getSellAmount());
                }
            }
            List<SwStMarketingTicketOffineSell> ticketOffineSells = swStMarketingTicketDTO.getTicketOffineSells();
            for (SwStMarketingTicketOffineSell ticketOffineSell : ticketOffineSells) {
                BigDecimal wechatSellAmount = ticketOffineSell.getWechatSellAmount();
                BigDecimal alipaySellAmount = ticketOffineSell.getAlipaySellAmount();
                totalElectronicAmount = totalElectronicAmount.add(wechatSellAmount).add(alipaySellAmount);
            }
        }
        return totalElectronicAmount;
    }
}
